using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;

using LogAnalyzer.Controls;
using LogAnalyzer.Grabbers;

namespace LogAnalyzer.Dialogs
{
    public partial class SingleViewer : Form
    {
        GrabberBase _grabber;
        private Point _location = Point.Empty;
        private Size _size = Size.Empty;
        private FormWindowState _windowState = FormWindowState.Normal;
        private bool _loadCompleted = false;
        private bool _initPositionSpecified = false;


        public SingleViewer(GrabberBase grabber, Form mdiParent)
        {
            InitializeComponent();
            viewerMain.SetContainer(this);

            this.MdiParent = mdiParent;

            _grabber = grabber;
            InitGrabber();
        }


        private void InitGrabber()
        {
            if (_grabber != null)
            {
                _grabber.NewStringIncoming += new NewStringIncomingHandler(_grabber_NewStringIncoming);
                _grabber.NewStringIncomingUnfiltered += new NewStringIncomingHandler(_grabber_NewStringIncomingUnfiltered);
                _grabber.ClearViewer += new ClearViewerHandler(_grabber_ClearViewer);
            }
        }


        public void UpdateTitle()
        {
            if (_grabber == null)
            {
                this.Text = "No grabber bound";
            }
            else
            {
               this.Text = _grabber.TextForViewer;
            }
        }


        private void _grabber_NewStringIncoming(object sender, NewStringIncomingEventArgs e)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new NewStringIncomingHandler(_grabber_NewStringIncoming), new object[] { sender, e });
                return;
            }

            viewerMain.AppendText(e.IncomingString);
        }
        private void _grabber_NewStringIncomingUnfiltered(object sender, NewStringIncomingEventArgs e)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new NewStringIncomingHandler(_grabber_NewStringIncomingUnfiltered), new object[] { sender, e });
                return;
            }

            SetNewLastLine(e.IncomingString);
        }
        private void _grabber_ClearViewer()
        {
            if (InvokeRequired)
            {
                Invoke(new ClearViewerHandler(_grabber_ClearViewer));
                return;
            }

            viewerMain.Clear();
        }


        private delegate void SetNewLastLineHandler(string s);
        private void SetNewLastLine(string s)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new SetNewLastLineHandler(SetNewLastLine), new object[] { s });
                return;
            }

            string line = "\n" + s.Replace("\r\n", "\n").Trim('\n');
            if (line.Length > 1)
            {
                viewerLastLine.Text = line.Substring(line.LastIndexOf('\n') + 1);
            }
        }


        private void SingleViewer_FormClosing(object sender, FormClosingEventArgs e)
        {
            _grabber.Dispose();
        }
         
        
        
        public GrabberBase InnerGrabber
        { 
            get { return _grabber; }
        }

        public ContextMenuStrip DropDownMenu
        {
            get { return viewerMain.DropDownMenu; }
        }

        public bool LastLineVisible
        {
            get { return panLastLine.Visible; }
            set { panLastLine.Visible = value; }
        }


        public void SaveConfig(XmlNode nodeSingleViewer)
        {
            XmlDocument xml = nodeSingleViewer.OwnerDocument;

            string t = _location.Y.ToString();
            string l = _location.X.ToString();
            string w = _size.Width.ToString();
            string h = _size.Height.ToString();
                        
            nodeSingleViewer.Attributes.Append(xml.CreateAttribute("t")).Value = t;
            nodeSingleViewer.Attributes.Append(xml.CreateAttribute("l")).Value = l;
            nodeSingleViewer.Attributes.Append(xml.CreateAttribute("w")).Value = w;
            nodeSingleViewer.Attributes.Append(xml.CreateAttribute("h")).Value = h;
            nodeSingleViewer.Attributes.Append(xml.CreateAttribute("ws")).Value = WindowState.ToString();

            XmlNode nodeGrabber = xml.CreateElement("grabber");
            nodeSingleViewer.AppendChild(nodeGrabber);
            _grabber.SaveConfig(nodeGrabber);

            XmlNode nodeViewer = xml.CreateElement("viewer");
            nodeSingleViewer.AppendChild(nodeViewer);
            viewerMain.SaveConfig(nodeViewer);
        }

        public void LoadConfig(XmlNode nodeSingleViewer)
        {
            string t = nodeSingleViewer.Attributes["t"].Value;
            string l = nodeSingleViewer.Attributes["l"].Value;
            string w = nodeSingleViewer.Attributes["w"].Value;
            string h = nodeSingleViewer.Attributes["h"].Value;
            string ws = nodeSingleViewer.Attributes["ws"].Value;

            _location = new Point(int.Parse(l), int.Parse(t));
            _size = new Size(int.Parse(w), int.Parse(h));
            _windowState = (FormWindowState)Enum.Parse(typeof(FormWindowState), ws);
            _initPositionSpecified = true;

            XmlNode nodeGrabber = nodeSingleViewer.SelectSingleNode("grabber");
            XmlNode nodeViewer = nodeSingleViewer.SelectSingleNode("viewer");

            viewerMain.LoadConfig(nodeViewer);

            Type grabberType = Type.GetType(nodeGrabber.Attributes["type"].Value);
            if(_grabber !=null)
            {
                _grabber.Dispose();
                _grabber = null;
            }
            _grabber = (GrabberBase)Activator.CreateInstance(grabberType);
            _grabber.LoadConfig(nodeGrabber);
            InitGrabber();
        }

        private void SingleViewer_Load(object sender, EventArgs e)
        {
            if (_initPositionSpecified)
            {
                this.Location = _location;
                this.Size = _size;
                WindowState = _windowState;
            }
            else
            {
                _location = this.Location;
                _size = this.Size;
            }


            if (_grabber != null)
            {
                try
                {
                    _grabber.StartGrab();
                    UpdateTitle();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(
                        "Exception starting grabber for viewer!\r\n\r\n" + ex.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }

            _loadCompleted = true;
        }

        private void SingleViewer_Resize(object sender, EventArgs e)
        {
            if (_loadCompleted == false)
                return;

            if (WindowState == FormWindowState.Normal)
            {
                _location = this.Location;
                _size = this.Size;
            }
        }

        private void SingleViewer_Move(object sender, EventArgs e)
        {
            if (_loadCompleted == false)
                return;

            if (WindowState == FormWindowState.Normal)
            {
                _location = this.Location;
                _size = this.Size;
            }
        }


    }
}